using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Microsoft.DirectX;
using OpenPanekitEditor;
using OpenPanekitEditor.Panel;
using NovodexWrapper;

namespace OriginalPanels
{
    [PanelAttribute("Original::Wheel", IsDeadEnd=true ,HasPivot=true, LocalD3DModelName = "Model\\Wheel_P.X", PivotD3DModelName = "Model\\Wheel_S.X")]
    public class Wheel : PanelBase, IPanel
    {
        public Image IconImage { get { return Properties.Resources.ElementIcon_Wheel; } }
        Matrix l_to_r_matrix = Matrix.Identity;
        public Matrix LocalToRootMatrix
        {
            get { return l_to_r_matrix; }
            set { l_to_r_matrix = value; }
        }
        Matrix j_to_r_matrix = Matrix.Identity;
        public Matrix PivotToRootMatrix
        {
            get {
                if (wheelShape != null)
                {
                    //return wheelShape.GlobalPose;
                    return Matrix.Translation(0, 0, wheelShape.getSuspensionTravel()) * Matrix.Translation(0, 0, OpenPanekitEditor.Panel.PanelUtil.PanelUnit / 2) * l_to_r_matrix;
                    
                }
                else
                {
                    return j_to_r_matrix;
                }
            }
            set { j_to_r_matrix = value; }
        }

        public Matrix PivotMatrix
        {
            get { return Matrix.Identity; }
            set { }
        }
        public Wheel()
        {
            ParameterDictionary[typeof(WheelParameter_Torque)] = new WheelParameter_Torque();
            ParameterDictionary[typeof(WheelParameter_Brake)] = new WheelParameter_Brake();
        }
        NxWheelShape wheelShape;
        NxWheelShapeDesc wheelShapeDesc = null;
        NxSpringDesc wheelSpring = null;
        protected Vector3 local_axis;
        public override NxActor InitNx(NxScene scene, NxActor parent, Matrix pmatrix)
        {
            const float sus_travel = 0.15f;
            Matrix nx_localmatrix_inv = Matrix.RotationY((float)Math.PI / 2) * Matrix.RotationX(-(float)Math.PI / 2) * pmatrix;
            wheelShapeDesc = new NxWheelShapeDesc(0.4f, sus_travel, 0.5f, 0, 0f, 0f, (float)(0), nx_localmatrix_inv);
            wheelSpring = new NxSpringDesc(30000, 2000, sus_travel);
            wheelShapeDesc.setSuspension(wheelSpring);
            wheelShapeDesc.skinWidth = 0.4f;

            wheelShape = (NxWheelShape)parent.createShape(wheelShapeDesc);
            wheelShape.setMotorTorque(0f);
            wheelShape.FlagWheelAxisContactNormal = true;
            NxTireFunctionDesc t = wheelShape.LateralTireForceFunction;
            t.stiffnessFactor = 20000;

            wheelShape.LateralTireForceFunction = t;
            //wheelShape.FlagDynamicDynamicCCD = true;
            //wheelShape.FlagAxleSpeedOverride = true;
            /*
            const float sus_travel = 0.3f;
            nx_localmatrix = jointtrans * localtrans * pmat;
            Matrix nx_localmatrix_inv = Matrix.RotationY((float)Math.PI / 2) * Matrix.RotationX(-(float)Math.PI / 2) * nx_localmatrix;
            //nx_localmatrix_inv.Invert();
            wheelShapeDesc = new NxWheelShapeDesc(0.4f, sus_travel, 0.5f, 0, 0f, 0f, (float)(0), nx_localmatrix_inv);
            wheelSpring = new NxSpringDesc(3000, 200, sus_travel);
            wheelShapeDesc.setSuspension(wheelSpring);
            wheelShapeDesc.skinWidth = 0.4f;

            wheelShape = (NxWheelShape)nx_actor.createShape(wheelShapeDesc);
            wheelShape.setMotorTorque(0f);
            wheelShape.FlagWheelAxisContactNormal = true;
            NxTireFunctionDesc t = wheelShape.LateralTireForceFunction;
            t.stiffnessFactor = 20000;

            wheelShape.LateralTireForceFunction = t;
            wheelShape.FlagDynamicDynamicCCD = true;
            wheelShape.FlagAxleSpeedOverride = true;
            //wheelShape.FlagFluidActorReaction = true;
            //wheelShape.FlagPointContactForce = true;
            //wheelShape.FlagTriggerEnable = true;

            return (NxShape)wheelShape;
            */
            return null;
        }
        public override void UpdateNxParameter(float dt)
        {
            wheelShape.setMotorTorque(ParameterDictionary[typeof(WheelParameter_Torque)].Value);
            wheelShape.setBrakeTorque(ParameterDictionary[typeof(WheelParameter_Brake)].Value);
        }
    }
    public class WheelParameter_Torque : OpenPanekitEditor.Panel.Parameter
    {
        public override float UpperLimit
        {
            get { return 1000f; }
        }
        public override float LowerLomit
        {
            get { return -1000f; }
        }
        public override float Quantize
        {
            get { return 100f; }
        }
        public override String Title
        {
            get { return Resouces.Strings.SettingParameter_WheelTorque; }
        }
        public override String Unit
        {
            get { return "N/P"; }
        }
        public override bool CanAssignControl
        {
            get { return true; }
        }
    }
    public class WheelParameter_Brake : OpenPanekitEditor.Panel.Parameter
    {
        public override float UpperLimit
        {
            get { return 1000f; }
        }
        public override float LowerLomit
        {
            get { return 0f; }
        }
        public override float Quantize
        {
            get { return 100f; }
        }
        public override String Title
        {
            get { return Resouces.Strings.SettingParameter_WheelBrake; }
        }
        public override String Unit
        {
            get { return "N"; }
        }
        public override bool CanAssignControl
        {
            get { return true; }
        }
    }
}
